﻿using AuSys.Controllers.System;
using AuSys.Services.App.Logging;
using Serilog;
using Serilog.Events;

namespace AuSys.Services.App.Logging
{
    public static class SerilogService
    {
        public static IServiceCollection AddSerilog(this IServiceCollection services, IConfiguration config)
        {
            var logger = new LoggerConfiguration()
                .ReadFrom.Configuration(config)
                .CreateLogger();
            services.AddSerilog(logger);
            Log.Logger = logger;
            return services;
        }
        public static IApplicationBuilder UseRequestLogging(this IApplicationBuilder builder, IConfiguration config)
        {
            var staticFileControllerName
                = nameof(StaticFileController).Replace("Controller", "");
            builder.UseSerilogRequestLogging(options =>
            {
                var mt = config["Serilog:AspNetCore:RequestLogging:MessageTemplate"];
                if (!string.IsNullOrWhiteSpace(mt))
                {
                    options.MessageTemplate = mt;
                }
                options.GetLevel = (hc, x, ex) =>
                {
                    if (ex is not null)
                        return LogEventLevel.Error;
                    if (x > 4000)
                        return LogEventLevel.Warning;
                    if (hc.Request.RouteValues.TryGetValue("controller", out var controllerName))
                    {
                        var cn = controllerName;
                        if(cn is string cns && cns == staticFileControllerName)
                            return LogEventLevel.Debug;
                    }
                    return LogEventLevel.Information;
                };
                options.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
                {
                    var requestQuery = httpContext.Request.QueryString;
                    var requestLength = httpContext.Request.ContentLength ?? 0;
                    var responseLength = httpContext.Response.ContentLength ?? 0;
                    diagnosticContext.Set("QueryString", requestQuery);
                    diagnosticContext.Set("RequestLength", requestLength);
                    diagnosticContext.Set("ResponseLength", responseLength);
                };
            });

            //为logger提供UserId的中间件（必须放在logger中间件后面）
            builder.UseMiddleware<SerilogUserIdReadingMiddleware>();
            return builder;
        }
    }
}
